package com.meefo.meeting.common;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.meefo.meeting.config.Constants;
import net.sf.json.JSONObject;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class QRCodeGenerate {
    /**
     * 会议二维护生成
     *
     * @param projectId 会议uuid
     * @param url       扫码后处理接口地址
     * @return
     */
    public static JSONObject getMeetingQRCode(String projectId, String url) {
        JSONObject jsonObject = new JSONObject();
        String filename = projectId;
        String path = Constants.tomcatUrl + "/resources/meetingQRCode/";
        String meetingNameText = projectId;
        System.out.println(path + "/" + filename);
        try {
            File folder = new File(path);
            if (!folder.exists())
                folder.mkdirs();
            filename= StringFilter(filename);
            filename=filename+ ".png";
            File file = new File(path + "/" + filename);
            if (!file.exists())
                file.createNewFile();
            OutputStream ous = new FileOutputStream(file);
            Map<EncodeHintType, String> map = new HashMap();
            //设置编码
            map.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            map.put(EncodeHintType.MARGIN, "2");
            //生成二维码
            BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 600, 600, map);
            MatrixToImageWriter.writeToStream(bitMatrix, "png", ous);

            // 绘制图片
            BufferedImage backgroundImage = new BufferedImage(800, 900, BufferedImage.TYPE_INT_RGB);
            BufferedImage image = ImageIO.read(file);
            Graphics2D rng = backgroundImage.createGraphics();
            //设置笔刷颜色
            rng.setColor(new Color(43, 82, 171));
            rng.fillRect(0, 0, 1000, 1000);
            rng.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP));
            rng.drawImage(image, 100, 100, 600, 600, null);
            // 绘制文字
            rng.setColor(Color.white);
            Font font = new Font("黑体", Font.BOLD, 30);
            rng.setFont(font);
            int l = 0;
            java.util.List<String> line_list = getStrList(meetingNameText, font, 630, rng);

            for (int i = 0; i < line_list.size(); i++) {
                String line_str = line_list.get(i);
                rng.drawString(line_str, 100, 700+(i + 2) * 35);//35为每行的高度
            }
            rng.dispose();
            image = backgroundImage;
            image.flush();
            ImageIO.write(image, "png", file);
            jsonObject.put("result", true);
            jsonObject.put("httppath", Constants.proUri + "meetingQRCode/" + filename);
            jsonObject.put("path", Constants.tomcatUrl + "resources/meetingQRCode/" + filename);
            return jsonObject;
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("二维码生成失败。");
            jsonObject.put("result", false);
            return jsonObject;
        }
    }

    public   static   String StringFilter(String   str)  {
        // 只允许字母和数字
        // String   regEx = "[^a-zA-Z0-9]";
        // 清除掉所有特殊字符
        String regEx="[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
        Pattern p   =   Pattern.compile(regEx);
        Matcher m   =   p.matcher(str);
        return   m.replaceAll("").trim();
    }
    public static List<String> getStrList(String info, Font font, Integer width, Graphics2D g){
        ArrayList<String> line_list = new ArrayList<>();
        FontRenderContext frc = g.getFontRenderContext();
        g.getFontRenderContext();
        Rectangle2D stringBounds = font.getStringBounds(info, frc);
        double fontWidth = stringBounds.getWidth();
        if (fontWidth <= width) {
            line_list.add(info);
        } else {
            int text_width = width;//输出文本宽度,这里就以画布宽度作为文本宽度测试
            double bs = fontWidth / text_width;//文本长度是文本框长度的倍数
            int line_char_count = (int) Math.ceil(info.length() / bs)+3;//每行大概字数
            int begin_index = 0;
            while (begin_index < info.length()) {
                int end_index = begin_index + line_char_count;
                if (end_index >= info.length()) {
                    end_index = info.length();
                }
                String line_str = info.substring(begin_index, end_index);
                Rectangle2D tempStringBounds = font.getStringBounds(line_str, frc);
                int tzcs = 0;//调整次数
                int tzzs = 1;//调整字数,临时文本的字符串长度大于要求的文本宽度时,每次减少临时文本的字数,然后重新测量文本宽度
                while (tempStringBounds.getWidth() > text_width) {
                    line_str = line_str.substring(0, line_str.length() - tzzs);//每次向前 tzzs 个字符重新计算(待优化)
                    tempStringBounds = font.getStringBounds(line_str, frc);
                    tzcs++;
                }
                System.out.println("调整" + (end_index - begin_index - line_str.length()) + "个数字,调整了" + tzcs + "次,当前行宽度:" + tempStringBounds.getWidth());
                line_list.add(line_str);
                begin_index = begin_index + line_str.length();
            }
        }

        return line_list;
    }
}
